package com.jmp.security.grant.gzhApi;

import com.jmp.base.dto.AccountResponse;
import com.jmp.security.base.ClientDetail;
import com.jmp.security.base.UserDetail;
import com.jmp.security.base.UserDetailService;
import com.jmp.security.grant.wx.WxLoginService;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import one.stand.dto.WechatLoginDto;
import one.stand.dto.WechatUserInfoDto;
import one.stand.model.User;
import one.stand.service.UserService;
import one.stand.service.user.UserAdminService;

import java.util.Objects;

@Slf4j
public class GzhApiWxUserDetailServiceImpl implements UserDetailService<GzhApiWxRequestDetail> {
    private UserAdminService userAdminService;
    private WxLoginService wxLoginService;
    private UserService userService;

    public GzhApiWxUserDetailServiceImpl(UserAdminService userAdminService, WxLoginService wxLoginService, UserService userService) {
        this.userAdminService = userAdminService;
        this.wxLoginService = wxLoginService;
        this.userService = userService;
    }

    @Override
    public UserDetail get(GzhApiWxRequestDetail requestDetail, ClientDetail clientDetail) {
        WxUserDetail userDetail = new WxUserDetail();
        publicOauth(requestDetail, clientDetail, userDetail);

        if (Objects.isNull(userDetail.getUserModel())) {
            saveUser(requestDetail, clientDetail.getCompanyAccountModel().getCompanyId(), userDetail);
        } else {
            updateUser(userDetail.getUserModel(), requestDetail, clientDetail, userDetail.getWechatLoginDto(), userDetail.getUserInfoDto());
        }

        User inModel = userAdminService.getByUserId(userDetail.getUserModel().getUserId());//重新获取最新User信息
        userDetail.setUserModel(inModel);

        return userDetail;
    }

    private void updateUser(User inModel, GzhApiWxRequestDetail request, ClientDetail clientDetail, WechatLoginDto wechatLoginDto, WechatUserInfoDto userInfoDto) {
        User userModel = new User();
        final boolean isUpdateUserInfo = userAdminService.isVisit(inModel.getAvatarUrl()) && Objects.nonNull(userInfoDto);
        if (isUpdateUserInfo) {
            userModel.setUserId(inModel.getUserId());
            userModel.setNickeName(userInfoDto.getNickName());
            userModel.setAvatarUrl(userInfoDto.getAvatarUrl());
            userModel.setGender(userInfoDto.getGender());
            userModel.setCity(userInfoDto.getCity());
            userModel.setProvince(userInfoDto.getProvince());
            userModel.setCountry(userInfoDto.getCountry());
        }
        if (Objects.nonNull(userModel.getUserId())) {
            userService.update(userModel);
        }
    }

    private void saveUser(GzhApiWxRequestDetail request, Integer companyId, WxUserDetail userDetail) {
        WechatLoginDto wechatLoginDto = userDetail.getWechatLoginDto();
        WechatUserInfoDto userInfoDto = userDetail.getUserInfoDto();
        User inModel = new User();
        if (Objects.nonNull(userInfoDto)) {
            inModel.setNickeName(userInfoDto.getNickName());
            inModel.setAvatarUrl(userInfoDto.getAvatarUrl());
            inModel.setGender(userInfoDto.getGender());
            inModel.setCity(userInfoDto.getCity());
            inModel.setProvince(userInfoDto.getProvince());
            inModel.setCountry(userInfoDto.getCountry());
        }
        inModel.setUnionid(wechatLoginDto.getUnionId());
        inModel.setEnterpriseId(companyId);
        inModel.setGzhState(UserAdminService.GZH_STATE_GZH);
        userService.saveUser(inModel);

        userDetail.setUserModel(inModel);

        userService.saveUserLoginWx(inModel.getUserId(), request.getLoginEnum().getAccountType(), request.getCompanyKey(), wechatLoginDto.getOpenId());
    }

    private void publicOauth(GzhApiWxRequestDetail request, ClientDetail clientDetail, WxUserDetail userDetail) {
        AccountResponse companyAccountModel = clientDetail.getCompanyAccountModel();
        WechatLoginDto wechatLoginDto = wxLoginService.loginBack(request.getCode(), companyAccountModel.getAppId(), companyAccountModel.getAppSecret());
        WechatUserInfoDto userInfoDto = wxLoginService.getUserInfo(wechatLoginDto.getAccessToken(), wechatLoginDto.getOpenId());
        User inModel = userService.getByUnionid(wechatLoginDto.getUnionId());

        userDetail.setWechatLoginDto(wechatLoginDto);
        userDetail.setUserInfoDto(userInfoDto);
        userDetail.setUserModel(inModel);
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class WxUserDetail extends UserDetail {
        private WechatLoginDto wechatLoginDto;
        private WechatUserInfoDto userInfoDto;
    }
}
